/**
 * 功能：WiFi广告机
 * 日期：2020-02-09
 * 版本：V1.0
 * 描述：烧录代码之后在个人手机wifi列表上可以显示很多 博哥你好帅
 */

#include <ESP8266WiFi.h>

// 因为需要用到8266 no-os sdk中的方法 所以需要引入该头文件
extern "C" {
#include <user_interface.h>
}

void initWiFi(); 
void sendBeacon(char *ssid);

void setup() {
  // put your setup code here, to run once:
  initWiFi();
}

void loop() {
  // put your main code here, to run repeatedly:
  sendBeacon("01 你好帅",1);
  sendBeacon("02 你好帅",2);
  sendBeacon("03 你好帅",3);
  sendBeacon("04 你好帅",4);
  sendBeacon("05 你好帅",5);
  sendBeacon("06 你好帅",6);
  sendBeacon("07 你好帅",7);
  sendBeacon("08 你好帅",8);
}

void initWiFi(){
  delay(1000);
  wifi_set_opmode(STATION_MODE); // 设置STA模式
  wifi_promiscuous_enable(1);    // 开启混杂模式
}

/**
 * 函数功能：发送 802.11 beacon
 * 参数：
 *   1. ssid 广告内容，不能超过 32字节
 *   2. channel 信道
 */
void sendBeacon(char *ssid,int channel){
  
  // byte channel = random(1,12);
  wifi_set_channel(channel);

  uint8_t beacon_frame[128]={
  /****************MAC Head start**********************/
  0x80,0x00, /*Fram Control 2字节 固定*/ 
  0x00,0x00,  /*Duration 2字节 固定*/
  0xff,0xff,0xff,0xff,0xff,0xff, /*DA 6字节 MAC地址 固定*/   
  0x01,0x02,0x03,0x04,0x05,0x06, /*SA 6字节 MAC地址 需要动态修改 很多手机会过滤mac相同的beacon，只显示其中一个热点*/
  0x01,0x02,0x03,0x04,0x05,0x06, /*BSSID 6字节 需要动态修改 和SA一样*/  
  0x30,0x4f, /*Seq-ctl 2字节 固定*/
  /**************MAC Head end************************/

  /**************Frame body start********************/
  0x80,0x51,0xcb,0x68,0xd0,0x00,0x00,0x00,/*Timestamp 8字节*/
  0xFF,0x00,  /*BeaconInterval*/
  0x01,0x04, /*CapabilityInfo*/
  /*SSID(ElementID(1 Byte)-Length(1 Byte)-Data(Length Bytes))*/
  0x00, /*ElementID Element ID为0则为ssid SSID的长度介于0至32字节之间*/
  0x00, /* Length SSID长度*/
  /* 接下来的length个字节 表示ssid 需要动态填充 字节不固定*/
  /*Supported Rates (ElementID(1 Byte)-Length(1 Byte)-Data(Length Bytes))*/
  /*DSPS(ElementID(1 Byte)-Length(1 Byte)-Channel(1 Byte)*/
  /*后面都是可选项 可以忽略不填*/
  /**************Frame body end********************/
  };

  /*填充 SA/BSSID*/
  beacon_frame[10] = beacon_frame[16] = random(256);
  beacon_frame[11] = beacon_frame[17] = random(256);
  beacon_frame[12] = beacon_frame[18] = random(256);
  beacon_frame[13] = beacon_frame[19] = random(256);
  beacon_frame[14] = beacon_frame[20] = random(256);
  beacon_frame[15] = beacon_frame[21] = random(256);
  
  /*填充 SSID(ElementID(1 Byte)-Length(1 Byte)-Data(Length Bytes))*/
  int ssidLen = strlen(ssid);
  beacon_frame[37] = ssidLen;

  for(int index = 0;index < ssidLen ; index++){
     beacon_frame[38+index] = ssid[index];
  }

  /*填充 Supported Rates (ElementID(1 Byte)-Length(1 Byte)-Data(Length Bytes))*/
  uint8_t supportRates[10] = {0x01,0x08,0x82,0x84,0x8b,0x96,0x24,0x30,0x48,0x6c};
  for(int index = 0;index < 10; index ++){
    beacon_frame[38+ssidLen+index] = supportRates[index];
  }

  /*填充 DSPS(ElementID(1 Byte)-Length(1 Byte)-Channel(1 Byte)*/
  uint8_t dsps[3] = {0x03,0x01,0x00};
  dsps[2] = channel;
  for(int index = 0;index < 3; index ++){
    beacon_frame[48+ssidLen+index] = dsps[index];
  }

  /* 发送beacon */
  int frameSize = 51 + ssidLen;
  wifi_send_pkt_freedom(beacon_frame,frameSize,0);
  delay(10);
  wifi_send_pkt_freedom(beacon_frame,frameSize,0);
  delay(10);
  wifi_send_pkt_freedom(beacon_frame,frameSize,0);
  delay(100);
}
